<?php

namespace App\Services;

use App\Enum\CouponEnum;
use App\Models\DrivingTariff;
use App\Models\OrderDistance;
use App\Models\Orders;
use App\Models\PayOrder;
use App\Models\RefundOrder;
use App\Models\ServiceType;
use App\Models\Tariff;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;

class PassengerOrderService extends BaseService
{


    /**
     * 下单
     * @param string $order_no
     * @param string $service_type_id
     * @return Order
     *
     */
    public function createOrder(string $order_no, string $service_type_id_atr)
    {

        $order_info = Redis::GET($order_no);
        $order_info = json_decode($order_info, true);

        if (!$order_info)
            return_bob('订单不存在', 0, 200);

        if ($order_info['user_id'] != Auth::id())
            return_bob('非法操作', 0, 200);
        $service_type_arr = explode(',', $service_type_id_atr);

        $cur_service_type_cost = 0;
        if ($order_info['type'] != '1') {
            foreach ($service_type_arr as $service_type_id) {
                if (!isset($order_info['service_type'][$service_type_id])) return_bob('服务类型不存在', 0, 200);
                if ($cur_service_type_cost === 0 || $order_info['service_type'][$service_type_id]['cost']['unpaid_cost'] > $cur_service_type_cost['unpaid_cost'])
                    $cur_service_type_cost = $order_info['service_type'][$service_type_id]['cost'];

            }
        } else {
            $cur_service_type_cost = $order_info['service_type']['cost'];
        }

//        $cur_service_type_cost = $order_info['service_type'][$service_type_id]['cost'];
//        $redis                 = app("redis.connection");
//        $cur_service_type_info = $redis->get('service_type_info_'.$service_type_id);
//        $cur_service_type_info = json_decode($cur_service_type_info, true);
//        if(!$cur_service_type_info) {
//
//            $cur_service_type_info = ServiceType::query()->find($service_type_id)->toArray();
//            $redis->setex('service_type_info_'.$service_type_id, 86400, json_encode($cur_service_type_info));
//
//        }
        $city = \App\Models\ServiceCity::query()->where('city_id', $order_info['city_id'])->first('default_user_company_id');
        $order_model = new Orders();
        $order_model->city_id = $order_info['city_id'];
        $order_model->company_id = $city ? $city->default_user_company_id : 1;
        $order_model->driver_id = 0;
        $order_model->user_id = Auth::id();
        // $order_model->user_id              =$order_info['user_id'];

        $order_model->service_type_id = $order_info['type'] == '1' ? $service_type_id_atr : 0;
        $order_model->call_service_type_id = $service_type_id_atr;
        $order_model->car_id = 0;
        //$order_model->service_id      = $cur_service_type_info['service_id'];
        $order_model->order_sn = $this->getOrderSn();
        $order_model->predict_price = $cur_service_type_cost['unpaid_cost'];
//        $order_model->user_coupon_id       = $cur_service_type_cost['user_coupon_id'];
//        $order_model->coupon_price         = $cur_service_type_cost['coupon_cost'];
        $order_model->source = 1;
        $order_model->status = $cur_service_type_cost['is_prepayment'] ? '0' : '1';
        $order_model->types = (int)$order_info['types'] ? $order_info['types'] : 0; //代驾类型
        $order_model->type = (string)$order_info['type']; //订单类型
        DB::beginTransaction();

        if (!$order_model->save())
            return_bob('下单失败，请稍后重试', 0, 200);

        $order_distance_model = new OrderDistance();
        $order_distance_model->order_id = $order_model->id;
        $order_distance_model->book_start = $order_info['origin_name'];
        $order_distance_model->book_end = $order_info['destination_name'];
        $order_distance_model->book_start_coord = $order_info['origin'];
        $order_distance_model->book_end_coord = $order_info['destination'];
        $order_distance_model->book_time = $order_info['boarding_time'];

        if (!$order_distance_model->save()) {

            DB::rollBack();
            return_bob('下单失败，请稍后重试', 0, 200);

        }

        if ($cur_service_type_cost['is_prepayment'] == 1) { //需要预支付乘车费

            /*添加支付订单*/
            $pay_order = new PayOrder();
            $pay_order->order_id = $order_model->id;
            $pay_order->sn = uniqid();
            $pay_order->user_id = $order_model->user_id;
            $pay_order->price = $order_model->predict_price;
            $pay_order->price = $order_model->predict_price;
            $pay_order->type = 1;
            $pay_order->status = 0;

            if (!$pay_order->save()) {

                DB::rollBack();
                return_bob('下单失败，请稍后重试', 0, 200);

            }

        }

        DB::commit();

        return $order_model;
    }


    /**
     * 获取订单编号
     */
    public function getOrderSn()
    {

        $YmdHi_date = date('YmdHi');
        $redis_key = $YmdHi_date . 'order_sn';

        $redis = app("redis.connection");
        $redis->incr($redis_key);
        $next_sn = $redis->get($YmdHi_date . 'order_sn');

        if ($next_sn == 1) // 新增
            $redis->expire($redis_key, 60); // 设置过期时间

        return 1 . $YmdHi_date . str_pad($next_sn, 5, '0', STR_PAD_LEFT);

    }


    /**
     * 根据订单获取取消规则
     * @param object $order
     * @return \Illuminate\Database\Eloquent\HigherOrderBuilderProxy|mixed
     */
    public function getCancelRuleByOrder(object $order)
    {
        if (!$order->company_id || !$order->service_type_id) return false;

        if ($order->type == '0') {
            return $this->AccountabilityCancel($order); //网约车
        }
        return $this->drivingAccountabilityCancel($order); //代驾
    }

    /**
     * 网约车其它设置
     * @param object $order
     * @return mixed
     */
    public function AccountabilityCancel(object $order)
    {
        $redis = app("redis.connection");
        $accountability_cancel_key = "accountability_cancel_{$order->company_id}_{$order->service_type_id}";
        $accountability_cancel = $redis->get($accountability_cancel_key);
        $accountability_cancel = json_decode($accountability_cancel, true);
        if (!$accountability_cancel) {
            $tariff = Tariff::query()
                ->where('company_id', $order->company_id)
                ->where('type', 1)
                ->where('service_type_id', $order->service_type_id)
                ->where('open_time', '<=', date('Y-m-d H:i:s'))
                ->select(['other_settings'])
                ->orderByDesc('open_time')
                ->first();
            $accountability_cancel = $tariff->other_settings;
            $redis->setex($accountability_cancel_key, 86400, json_encode($accountability_cancel)); //缓存一天
        }
        return $accountability_cancel;
    }

    /**
     * 代驾其它设置
     */
    public function drivingAccountabilityCancel(object $order)
    {
        $redis = app("redis.connection");
        $accountability_cancel_key = "accountability_{$order->company_id}_{$order->service_type_id}";
        $accountability_cancel = $redis->get($accountability_cancel_key);
        $accountability_cancel = json_decode($accountability_cancel, true);
        if (!$accountability_cancel) {
            $tariff = DrivingTariff::query()
                ->where('company_id', $order->company_id)
                ->where('type', 1)
                ->where('service_type_id', $order->service_type_id)
                ->where('open_time', '<=', date('Y-m-d H:i:s'))
                ->select(['other_settings'])
                ->orderByDesc('open_time')
                ->first();
            $accountability_cancel = $tariff->other_settings;
            $redis->setex($accountability_cancel_key, 86400, json_encode($accountability_cancel)); //缓存一天
        }
        return $accountability_cancel;
    }


    /**
     * 取消订单
     * @param object $order
     * @return object
     * @throws \App\Exceptions\BobException
     */
    public function cancel(object $order)
    {

        $cancel_price = 0;
        $cancel_time = time();
        if ($order->status == 2) { //已接单

            $accountability_cancel = $this->getCancelRuleByOrder($order);
            $is_accountability = $cancel_time >= $order->receive_time + $accountability_cancel['accountability_cancel_time'] * 60 ? 1 : 0;
            $cancel_price = $is_accountability ? $accountability_cancel['accountability_cancel_price'] : 0;

        }

        $order->status = '-1';
        $order->cancel_price = $cancel_price;
        $order->cancel_status = 0;
        $order->cancel_time = $cancel_time;
        $refund_price = $order->real_price - $order->cancel_price;

        DB::beginTransaction();
        if ($refund_price > 0) { //有退款金额
            $order->cancel_status = 2;
            $pay_order_info = PayOrder::query()
                ->where('order_id', $order->id)
                ->where('status', 1)
                ->where('type', 1)
                ->select(['id', 'sn'])
                ->first();
            if (!$pay_order_info)
                return_bob('订单异常！', 0, 200);
            $refund_order_model = new RefundOrder();
            $refund_order_model->order_id = $order->id;
            $refund_order_model->sn = uniqid();
            $refund_order_model->pay_order_id = $pay_order_info->id;
            $refund_order_model->pay_order_sn = $pay_order_info->sn;
            $refund_order_model->user_id = $order->user_id;
            $refund_order_model->price = $refund_price;
            $refund_order_model->time = $cancel_time;
            $refund_order_model->type = 1;
            $refund_order_model->status = 0;
            if (!$refund_order_model->save()) {
                DB::rollBack();
                return_bob('系统繁忙', 0, 200);
            }

        }
        if ($refund_price < 0) { //待补款
            $order->cancel_status = 1;
            $pay_order_model = new PayOrder();
            $pay_order_model->order_id = $order->id;
            $pay_order_model->sn = uniqid();
            $pay_order_model->user_id = $order->user_id;
            $pay_order_model->price = abs($refund_price);
            $pay_order_model->type = 2;
            $pay_order_model->status = 0;
            if (!$pay_order_model->save()) {
                DB::rollBack();
                return_bob('系统繁忙', 0, 200);
            }
        }

//        $pay_order_pending = PayOrder::query()->where('order_id', $order->id)->where('status', 0)->where('type', 1)->first(); 注释 已取消待支付预付款状态显示
//        if($pay_order_pending) { //已生成待 支付订单
//
//            $pay_order_pending->status = -1; //取消
//
//            if( $pay_order_pending->save() === false ) {
//                DB::rollBack();
//                return_bob('系统繁忙', 0, 200);
//            }
//
//        }

        if ($order->save() === false) {
            DB::rollBack();
            return_bob('系统繁忙', 0, 200);
        }

        DB::commit();

        return $order;
    }


    /**
     * 根据服务类型获取我的订单列表
     * @param $service_type_id
     * @param $per_page
     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
     */
    public function getPageByServiceType($service_type_id, $per_page)
    {

        $select = ['id', 'service_type_id', 'status', 'created_at'];

        $order_model = Orders::query();
        $order_model->where('status', '!=', '0');
        $order_model->where('user_id', Auth::id());
        if ($service_type_id !== '')
            $order_model->whereIn('service_type_id', explode(',', $service_type_id));
        $page_data = $order_model->select($select)->with(['serviceType', 'distance'])->orderByDesc('created_at')->paginate($per_page);

        foreach ($page_data->items() as $item) {

            if ($item->service_type_id)
                $item->service_type_name = $item->serviceType->name;

            $item->origin_name = $item->distance->book_start;
            $item->destination_name = $item->distance->book_end;
            $item->time = date('m月d日 H:i', strtotime($item->created_at));
            $item->status_name = Orders::STATUS[$item->status];

            unset($item->created_at, $item->serviceType, $item->distance);
        }

        return $page_data;
    }


    /**
     * 乘客获取订单详情
     * @param $id
     */
    public function getDetail($id)
    {

        if (!$id)
            return_bob('订单ID不能为空', 0, 200);

        $order_select = [
            //id， 服务类型ID，状态， 取消责任费， 过路费， 停车费， 已支付金额， 实际行程费用, 优惠金额, 用户优惠券ID
            'id', 'service_type_id', 'status', 'cancel_price', 'toll_price', 'stop_price', 'real_price', 'cost_price', 'coupon_price', 'user_coupon_id',
            //应收价格（总费用）， 实际应收价格， 司机ID， 汽车ID， 状态， 用户ID， 创建时间
            'should_price', 'real_should_price', 'driver_id', 'car_id', 'status', 'user_id', 'created_at', 'km', 'minute', 'type'
        ];
        $order_info = Orders::query()->select($order_select)->find($id);
        //if( !$order_info || $order_info->user_id != Auth::id() || in_array($order_info->status, ['0', '1', '2', '3']) )
        if (!$order_info || $order_info->user_id != Auth::id())
            return_bob('订单ID有误', 0, 200);

        $return = [];
        $return['id'] = $order_info->id;
        $return['status'] = $order_info->status;
        $return['cancel_price'] = $order_info->cancel_price;
        $return['cost_price'] = $order_info->cost_price;
        $return['toll_price'] = $order_info->toll_price;
        $return['stop_price'] = $order_info->stop_price;
        $return['should_price'] = $order_info->should_price;
        $return['real_should_price'] = $order_info->real_should_price;
        $return['real_price'] = $order_info->real_price;
        $return['coupon_price'] = $order_info->coupon_price;
        $return['user_coupon_id'] = $order_info->user_coupon_id;
        $return['book_start'] = $order_info->distance->book_start;
        $return['book_end'] = $order_info->distance->book_end;
        $return['book_start_coord'] = $order_info->distance->book_start_coord;
        $return['book_end_coord'] = $order_info->distance->book_end_coord;
        $return['reality_start'] = $order_info->distance->reality_start;
        $return['reality_end'] = $order_info->distance->reality_end;
        $return['reality_start_coord'] = $order_info->distance->reality_start_coord;
        $return['reality_end_coord'] = $order_info->distance->reality_end_coord;
        $return['details_price'] = $order_info->distance->details;
        $return['km'] = $order_info->km;
        $return['minute'] = $order_info->minute;
        $return['type'] = $order_info->type;  //订单类型
        $return['time'] = date('m月d日 H:i', strtotime($order_info->created_at));

        if ($order_info->driver_id) {

            $return['driver_id'] = $order_info->driver_id;
            $return['driver_name'] = mb_substr($order_info->driver->real_name, 0, 1, 'utf-8') . '司机';
            $return['driver_phone'] = $order_info->driver->phone;
            $return['driver_avatar'] = $order_info->driver->head_image;
            $return['driver_score'] = $order_info->driver->score;

        }

        if ($order_info->car_id) {

            $return['car_id'] = $order_info->car_id;
            $return['car_color'] = $order_info->car->colour;
            $return['car_number'] = $order_info->car->number;
            if ($order_info->car->brand_id)
                $return['car_brand'] = $order_info->car->brand->name;

            $return['car_model'] = $order_info->car->model;

        }

        if ($order_info->status == 4) { //待确认

            if ($order_info->real_should_price === null) {//未生成订单

                //优惠券
                $passenger_user_coupon_service = new PassengerUserCouponService();
                $coupon_list = $passenger_user_coupon_service->getListAllByOrder($order_info->service_type_id, $order_info->cost_price, $order_info->distance->book_time);

                if ($coupon_list) {
                    foreach ($coupon_list as $coupon) {
                        $cur_coupon_price = $coupon['coupon']['type'] == CouponEnum::TypeProportion ?
                            $order_info->cost_price * (10 - $coupon['coupon']['coupon_value']) / 10 //折扣
                            : $coupon['coupon']['coupon_value']; //现金

                        $cur_coupon_price = intval($cur_coupon_price * 100) / 100;
                        if ($return['coupon_price'] == 0 || $return['coupon_price'] < $cur_coupon_price) {
                                $return['coupon_price'] = $cur_coupon_price;
                                $return['user_coupon_id'] = $coupon['id'];
                        }
                    }
                }
            }

        }

        if ($order_info->status == 6)  //已评论
            $return['comment_score'] = $order_info->comment->score;


        $pay_order = PayOrder::query()->where('order_id', $order_info->id)->where('status', 0)->first();
        if ($pay_order) { //待支付
            $return['pay_price'] = $pay_order->price;
            $return['pay_id'] = $pay_order->id;
        }

        $refund_order = RefundOrder::query()->where('order_id', $order_info->id)->first();
        if ($refund_order) { //退款
            $return['refund_status'] = $refund_order->status;
            if ($refund_order->status) { //已退款
                $return['refunded_price'] = $refund_order->price;
            } else { //待退款
                $return['refund_price'] = $refund_order->price;
                $return['refund_id'] = $refund_order->id;
            }
        }

        return $return;
    }


    /**
     * 获取当前用户上一条未处理订单
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|null
     */
    public function getPending()
    {

        $return = [
            'order_id' => 0, //订单ID
            'status' => 0, //状态
            'service_type_id' => 0, //当前服务类型
            'call_service_type_id' => 0, //呼叫服务类型
        ];

        $pay_order = PayOrder::query()
            ->where('user_id', Auth::id())
            ->where('status', 0)
            ->where('type', '!=', 1)//排除待支付预付款的订单
            ->orderByDesc('created_at')
            ->first();

        if ($pay_order) { //有待支付订单

            $return['order_id'] = $pay_order->order_id;
            return $return;

        }

        $order_info = Orders::query()
            ->where('user_id', Auth::id())
            ->orderByDesc('created_at')
            ->first(); //当前用户最近订单
        if ($order_info) {

            if (in_array($order_info->status, [0, 5, 6, -1, -2, -3])) //未支付预付款 已成功 已评论 乘客取消 司机取消 后台取消
                return $return;

            $return['order_id'] = $order_info->id;
            $return['status'] = $order_info->status;
            $return['service_type_id'] = $order_info->service_type_id;
            $return['call_service_type_id'] = $order_info->call_service_type_id;

        }

        return $return;
    }


    /**
     * 检查是否存在待处理订单
     * @return bool
     * @throws \App\Exceptions\BobException
     */
    public function checkPending()
    {
        $pending_order = $this->getPending();

        if ($pending_order['order_id'])
            return_bob('操作失败，存在待处理订单', 0, 200);

        return true;
    }


}
